home *** CD-ROM | disk | FTP | other *** search
- # SpecTcl, by S. A. Uhler
- # Copyright (c) 1994-1995 Sun Microsystems, Inc.
- #
- # See the file "license.txt" for information on usage and redistribution
- # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- #
- # extract all the info about a widget into an array
- # - configuration options
- # - geometry options
- # - misc stuff
-
- # {,i}pad[xy] and friends are problematic because both widgets and blt_table
- # use the same name.
-
- proc widget_extract {widget {array ""}} {
- global P
- dputs $widget
- if {$array == ""} {
- set array [winfo name $widget]
- }
- global $array
- upvar #0 $array data
- # outline_inhibit 1
-
- # extract widget attributes
- # don't extract command options if they already exist
-
- foreach option [$widget configure] {
- if {[llength $option] == 5} {
- set item [string trimleft [lindex $option 0] -]
- if {![string match *command* $item] || ![info exists data($item)]} {
- set data($item) [lindex $option 4]
- }
- }
- }
-
- # handle misc stuff
-
- foreach extra "tags master $P(other_items)" {
- if {![info exists data($extra)]} {
- set data($extra) {}
- }
- }
- if {![info exists data(item_name)]} {
- set data(item_name) [winfo name $widget]
- }
- set data(pathname) [winfo name $widget]
- set data(type) [string tolower [winfo class $widget]]
-
- # extract geometry attributes (assume blt_table for now)
- # need to handle row, col separately
-
- if {[winfo manager $widget] == "blt_table"} {
- regsub -all { -([^ ]+)} [blt_table info $widget] { \1} options
- regsub -all pad $options wad options ;# botch for padding
- regsub -all anchor $options align options ;# botch for padding
- array set $array [lrange $options 2 end]
- regexp {([0-9]+),([0-9]+)} [lindex $options 1] x \
- data(row) data(column)
- }
-
- # special (temporary) hack for frames
-
- if {$data(type) == "frame" && ![info exists data(panel)]} {
- dputs "setting $widget panel to {}"
- set data(panel) ""
- }
- # outline_inhibit 0
- }
-
- # change a widget to reflect the current value of its array
- # validation should already be done
- # mangle the pathname as needed
-
- proc widget_configure {array {root .can.f}} {
- global Widget_data
- upvar #0 $array data
- dputs $array $root
-
- set widget $root.$data(pathname)
- set class $data(type)
-
- # extract the widget and geometry options
-
- set config "$class $widget"
- set geom $data(row),$data(column)
- foreach i [array names data] {
- if {[info exists Widget_data(default:$class,$i)]} {
- if {![string match *command* $i]} {
- append config " -$i [list $data($i)]"
- }
- } elseif {[info exists Widget_data(default:table,$i)]} {
- append geom " -$i [list $data($i)]"
- }
- }
-
- # make the widget and manage it
-
- regsub -all {(-i?)wad([xy])} $geom {\1pad\2} geom ;# padding botch
- regsub -all align $geom anchor geom ;# padding botch
- dputs $config
- eval $config
- dputs "blt_table $data(master) $widget $geom"
- eval "blt_table $root$data(master) $widget $geom"
- return $widget
- }
-
- # try to change a field option, return message on error
- # name: The name of the widget (e.g. [winfo name $window])
- # item: The option to be changed
- # value: The value it wants to be set to
- # return value:
- # "": validation suceeded, the widget value and associate array was changed
- # <message>: Validation failed, reason is returned in result
-
- proc validate_field {name item value} {
- global Widget_data
- upvar #0 $name data
-
- # run the output filter (if any) to do data conversion and (some) validation
-
- dputs "validating: $name $item $value"
- if {[info exists Widget_data(outfilter:$item)]} {
- dputs out-filtering $name: $item=<$value>
- if {![$Widget_data(outfilter:$item) $name $item value]} {
- return $value
- }
- }
-
- # set the widget value
- # make sure to preserve any embedded "\n"'s in the value
-
- dputs $name
- if {[string compare [info commands .$name] .$name] == 0} {
- set widget .$name
- } else {
- set widget .can.f.$name
- }
- set class $data(type)
- set cmd ""
- if {[string match *command* $item]} {
- dputs skipping $item - its a command
- } elseif {[info exists Widget_data(default:$class,$item)]} {
- set cmd "$widget configure -$item \"[sub_bs $value 1]\""
- } elseif {[info exists Widget_data(default:table,$item)]} {
- set cmd [list blt_table configure $widget -$item $value]
- regsub -all {(-i?)wad([xy])} $cmd {\1pad\2} cmd ;# padding botch
- regsub -all align $cmd anchor cmd ;# padding botch
- } elseif {[info exists Widget_data(default:position,$item)]} {
- set base "blt_table .can.f$data(master) [blt_table info $widget]"
- if {$item == "row"} {
- set sub "$value,\\2"
- } else {
- set sub "\\1,$value"
- }
- regsub {([0-9]+),([0-9]+)} $base $sub cmd
- } else {
- dputs "unknown type: $item <- $value"
- set data($item) $value
- }
-
- # go set the value, and update the array
- dputs "($item) $cmd"
- set bad [catch "$cmd" msg]
- if {$bad} {
- return $msg
- } else {
- set data($item) $value
- return ""
- }
- }
-
- # do '\n' substitutions on a string, but leave commands and variables alone
-
- proc sub_bs {str {nosub 0}} {
- regsub -all {([][$])} $str {\\\1} str
- dputs $str
- if {$nosub} {
- return $str
- } else {
- return [subst $str]
- }
- }
-
-